import * as util from './util'
import * as step from '@flow-step/step-toolkit'
import {certificate} from '@flow-step/step-toolkit'
import {RedlineResult,RedlineInfo } from '@flow-step/step-toolkit/src/redline/redline';
import {installJDK} from './install'

import {chmod} from 'fs'

import {v4 as uuidv4} from 'uuid'
import process from 'process'
import path from 'path'
import * as readline from 'readline'
const FLOW_JOB_TOKEN: string = 'FLOW_JOB_TOKEN'

export const IS_LINUX = process.platform === 'linux'
export const IS_X64 = process.arch === 'x64'
export const SEP = path.sep

export async function execute() {
    if (!IS_LINUX) {
        step.error(`SpotbugsScan only supports Linux systems, Please use Linux`)
        process.exit(1)
    }
    if (!IS_X64) {
        step.error(`SpotbugsScan only supports X64, Please use X64`)
        process.exit(1)
    }

    //查找class 文件
    //查找所有class 文件
    const projectDir = process.env['PROJECT_DIR']
    const uuid = uuidv4()
    let reportDir = projectDir + SEP +"spotbugs"  +  SEP +uuid
    await util.createDirectory(reportDir)
    const classOutputFilePath = reportDir + SEP + 'classes.txt'
    // @ts-ignore
    await util.findClassFilesToFile(projectDir, classOutputFilePath)
    const report_html = 'report.html'

    const reportHtmlPath = reportDir + SEP + report_html
    step.info(`Preparing to install SpotBugs scan...`)

    await installJDK('jdk11', projectDir+ SEP +"jdk")

    const spotbugsBin = __dirname + SEP + 'spotbugs-4.9.8' + SEP + 'bin' + SEP + 'spotbugs'

    chmod(spotbugsBin, 0o755, (err) => {
        if (err) {
            step.error(`Error setting file permissions: ${err.message}`)
            process.exit(1)
        } else {
            step.info(`Permissions for ${spotbugsBin} set to 755`)
        }
    })

    const command = `${spotbugsBin} -textui -html -output ${reportHtmlPath} $(cat ${classOutputFilePath} | tr '\\n' ' ')\n`
    step.info(`Executing SpotBugs command: ${command}`)

    const exitCode = await step.exec.call('/bin/bash', ['-c', command])


    // 检查报告文件是否存在
    const fs = require('fs')
    if (!fs.existsSync(reportHtmlPath)) {
        step.error(`Report file was not generated: ${reportHtmlPath}`)
        step.error(`SpotBugs may not have found any class files to analyze`)

        // 检查 classes.txt 文件内容以便调试
        try {
            const classesContent = await fs.promises.readFile(classOutputFilePath, 'utf-8')
            step.info(`Classes file content (first 500 chars): ${classesContent.substring(0, 500)}`)
        } catch (err: any) {
            step.error(`Failed to read classes file: ${err.message}`)
        }

        process.exit(1)
    }


    step.info(`Report file successfully generated: ${reportHtmlPath}`)
    step.info(`Starting to parse SpotBugs report...`)

    //解析报告
    const reportWarnings = await util.parseReportHtml(reportHtmlPath)
    //校验红线
    const readlineResults = [] as RedlineResult[]
    const totalRedlineResult = {} as RedlineResult
    totalRedlineResult.key = 'Total'
    totalRedlineResult.title = '全部'
    totalRedlineResult.value = reportWarnings.totalWarnings
    totalRedlineResult.style = step.redline.Error
    readlineResults.push(totalRedlineResult)
    const highRedlineResult = {} as RedlineResult
    highRedlineResult.key = 'High'
    highRedlineResult.title = '高'
    highRedlineResult.value = reportWarnings.highWarnings
    highRedlineResult.style = step.redline.Error
    readlineResults.push(highRedlineResult)
    const mediumRedlineResult = {} as RedlineResult
    mediumRedlineResult.key = 'Medium'
    mediumRedlineResult.title = '中'
    mediumRedlineResult.value = reportWarnings.mediumWarnings
    mediumRedlineResult.style = step.redline.Warning
    readlineResults.push(mediumRedlineResult)
    const redlineInfo = {} as RedlineInfo
    redlineInfo.title = 'Java 安全扫描 Spotbugs'
    redlineInfo.reportUrl = `http://testing.rdc.aliyun.com/assets/${process.env['REGION_ID']}/${process.env['PIPELINE_ID']}/${uuid}/${report_html}`
    redlineInfo.readlineResults = readlineResults
    step.redline.redlineCheck(redlineInfo, process.env['CHECK_REDLINES'])

    let endpoint = await step.oss.getEndpoint(process.env['endpoint'] as string)
    if (!endpoint.startsWith('http://') && !endpoint.startsWith('https://')) {
        endpoint = 'https://' + endpoint;
    }
    step.info(`endpoint: ${endpoint}`)
    const flowJobToken: string | undefined =
        process.env[FLOW_JOB_TOKEN]

    if (flowJobToken == undefined) {
        let errMsg = 'missing FLOW_JOB_TOKEN'
        throw new Error(errMsg)
    }
    const ossRamStsCertificate = await step.certificate.getOssRamStsCertificate(flowJobToken, certificate.OssBucketType.ASSETS)
    const remoteStorage = new step.oss.OSSStorage({
        endpoint: endpoint,
        accessKeyID: ossRamStsCertificate.accessKeyId,
        accessKeySecret: ossRamStsCertificate.accessKeySecret,
        securityToken: ossRamStsCertificate.securityToken,
        bucket: ossRamStsCertificate.bucketName
    })
    step.info('upload report')

    const fileId = `${ossRamStsCertificate.ossPathPrefix}/${process.env['PIPELINE_ID']}/${uuid}/${report_html}`
    await step.oss.upload(remoteStorage, reportHtmlPath, fileId, undefined)

}
